package ch.bfh.ti.barcode.colorQrCode;

import com.google.zxing.Binarizer;
import com.google.zxing.LuminanceSource;
import com.google.zxing.NotFoundException;
import com.google.zxing.common.BitArray;
import com.google.zxing.common.BitMatrix;

/**
 * Replaces the HybridBinarizer or GlobalHistogramBinarizer. This implementation
 * doesn't analyze the luminance values. It takes the sensitivity from a
 * constructor parameter which makes it a lot faster.
 * 
 * @author Dominik von Burg
 * 
 */
public class SimpleBinarizer extends Binarizer {
	private int sensitivity;

	/**
	 * The LuminanceSource and sensitivity have to be set when instantiating a
	 * SimpleBinarizer. Those values can't be changed after.
	 * 
	 * @param source
	 *            The LuminanceSource with the luminance values of the barcode.
	 * @param sensitivity
	 *            Sensitivity for the black and white conversion of the color
	 *            channels. The higher the value the more colors turn black.
	 */
	protected SimpleBinarizer(LuminanceSource source, int sensitivity) {
		super(source);
		this.sensitivity = sensitivity;
	}

	@Override
	public Binarizer createBinarizer(LuminanceSource source) {
		return new SimpleBinarizer(source, 50);
	}

	@Override
	public BitMatrix getBlackMatrix() throws NotFoundException {
		LuminanceSource source = getLuminanceSource();

		int width = source.getWidth();
		int height = source.getHeight();

		BitMatrix matrix = new BitMatrix(width, height);

		byte[] sourceData = source.getMatrix();

		for (int y = 0; y < height; y++) {
			int posY = y * width;
			for (int x = 0; x < width; x++)
				if ((int) (sourceData[posY + x] & 0xff) < sensitivity)
					matrix.set(x, y);
		}

		return matrix;
	}

	@Override
	public BitArray getBlackRow(int row, BitArray bitArray)
			throws NotFoundException {
		LuminanceSource source = getLuminanceSource();
		byte[] rowData = new byte[source.getWidth()];
		source.getRow(row, rowData);

		BitArray array = new BitArray(rowData.length);

		for (int x = 0; x < rowData.length; x++)
			if ((int) (rowData[x] & 0xff) < sensitivity)
				array.set(x);

		return array;
	}

}
